﻿#include "pch.h"

CIndexWrapper::CIndexWrapper()
{
    memset((void *)this, 0, sizeof(CIndexWrapper));
}

void CIndexWrapper::printSelf(char *captionUpper, int32_t)
{
    char caption[1024];
    sprintf(caption, "%s:%s", captionUpper, "CIndexWrapper");
    print4x(this, sizeof(CIndexWrapper), caption);
    if (this->head)
    {
        sprintf(caption, "%s:%s", captionUpper, "CIndexWrapper.head");
        print4x(this->head, this->len * this->size, caption);
    }
    if (this->num)
    {
        sprintf(caption, "%s:%s", captionUpper, "CIndexWrapper.num");
        print4x(this->num, sizeof(int32_t), caption);
    }
    if (this->indexBuf)
    {
        sprintf(caption, "%s:%s", captionUpper, "CIndexWrapper.indexBuf");
        print4x(this->indexBuf, sizeof(IndexBuffer1), caption);
    }
    if (this->indexBuf20)
    {
        sprintf(caption, "%s:%s", captionUpper, "CIndexWrapper.indexBuf20");
        print4x(this->indexBuf20, sizeof(IndexBuffer2), caption);
    }
    if (this->indexBuf2)
    {
        sprintf(caption, "%s:%s", captionUpper, "CIndexWrapper.indexBuf2");
        print4x(this->indexBuf2, sizeof(IndexBuffer2), caption);
    }
}

// sub_1001A110
CIndexWrapper *CIndexWrapper::init(int32_t len)
{
    this->init_(len);
    this->initData();
    this->indexCount2 = len;
    return this;
};

// sub_1001E140
CIndexWrapper *CIndexWrapper::init_(int32_t len)
{
    void *data; // eax

    this->needFreeHead = true;
    data = new IndexBuffer1[len];
    this->head = data;
    if (data)
    {
        this->size = 20;
        this->len = len;
        memset(this->head, 0, this->size * this->len);
        this->num = &(this->numValue);
        *(this->num) = 0;
        this->tail = 0;
    }
    return this;
};

// sub_10002AE4
CIndexWrapper *CIndexWrapper::initData()
{
    memset(this->head, 0, sizeof(IndexBuffer1) * this->len);
    this->initHead();
    this->indexBuf20 = 0;
    this->indexBuf2 = 0;
    this->currentTail2 = 0;
    this->index1Flag = 0;
    this->baseTail = false;
    this->index2Flag = 0;
    return this;
};

// sub_10002B4D
IndexBuffer1 *CIndexWrapper::initHead()
{
    this->indexBuf = (IndexBuffer1 *)this->getHead();
    this->indexBuf->head = -1;
    this->indexBuf->tail = -1;
    this->indexBuf->itemCount = 0;
    this->indexBuf->flag = false;
    this->indexBuf->pIndex2 = NULL;
    return this->indexBuf;
};

// sub_1001B290
CBaseWrapper *CIndexWrapper::close(char flag)
{
    this->close();
    if (flag & 1)
    {
        delete this;
        return NULL;
    }
    return this;
};

// sub_10002A53
CBaseWrapper *CIndexWrapper::close()
{
    int32_t i;

    IndexBuffer1 *pIndex = (IndexBuffer1 *)this->head;
    for (i = 0; i < this->len; ++i)
    {
        if (pIndex[i].pIndex2)
        {
            delete[] (LPINT)pIndex[i].pIndex2;
        }
    }
    return this->close_();
};

// sub_1001A320
int32_t CIndexWrapper::isIndex1Valid()
{
    return this->numValue > 0 && this->indexBuf->head >= 0;
};

// sub_1001A3F0
int32_t CIndexWrapper::isIndex2Valid()
{
    return this->currentTail2 > 0 && this->indexBuf2->head2 >= 0;
};

// sub_10002C49
int32_t CIndexWrapper::cleanIndexBuf2()
{
    IndexBuffer1 *pBuf;

    if (this->currentTail2)
    {
        return false;
    }
    pBuf = this->getCurrentIndexBuf();
    if (pBuf)
    {
        pBuf->pIndex2 = NULL;
        pBuf->itemCount = 0;
    }
    delete[] this->indexBuf20;
    this->indexBuf20 = NULL;
    this->indexBuf2 = NULL;
    return true;
};

// sub_1001A080
IndexBuffer1 *CIndexWrapper::getCurrentIndexBuf()
{
    int32_t i;
    IndexBuffer1 *pIndex = (IndexBuffer1 *)this->head;

    if (!this->indexBuf20)
    {
        return NULL;
    }
    if (this->indexBuf && this->indexBuf->pIndex2 == this->indexBuf20)
    {
        return this->indexBuf;
    }
    for (i = 0; i < this->len; ++i)
    {
        if (pIndex[i].pIndex2 == this->indexBuf20)
        {
            return &pIndex[i];
        }
    }
    return NULL;
};

// sub_10002FCF
int32_t CIndexWrapper::setResultTypeCode(TDLLResultListItem *pRes, int32_t tail)
{
    int32_t tail2;
    int32_t head2;
    int32_t prevHeadOrTail;
    int32_t headOrTail;
    int32_t tailOrHead;
    int32_t j;
    int32_t *pNumber;
    int32_t l;
    int32_t i;
    int32_t k;
    int32_t m;
    IndexBuffer1 *pIdx;
    int32_t NumOfElements;
    int32_t NumOfElementsa;
    IndexBuffer1 *Base;

    Base = (IndexBuffer1 *)this->getHead();
    pNumber = this->getNumPointer();
    this->getLen();
    NumOfElements = *pNumber;
    if (*pNumber <= 0)
    {
        return 0;
    }
    qsort(Base, NumOfElements, sizeof(IndexBuffer1), compareFistAndSecond);
    for (i = 0; i < NumOfElements; ++i)
    {
        if (!Base[i].itemCount && Base[i].pIndex2)
        {
            delete[] ((int32_t *)Base[i].pIndex2);
            Base[i].pIndex2 = 0;
        }
        if ((int32_t)Base[i].head < 0 || (int32_t)Base[i].tail < 0)
        {
            for (j = i; j < NumOfElements; ++j)
            {
                if (Base[j].pIndex2)
                {
                    delete[] ((int32_t *)Base[j].pIndex2);
                    Base[j].pIndex2 = 0;
                }
            }
            size_t count = NumOfElements - j;
            if (count > (SIZE_MAX / 20))
            {
                std::cerr << "Memory size calculation overflow in function CIndexWrapper::setResultTypeCode." << std::endl;
                return 0;
            }
            size_t bytes = 20 * count;
            if (bytes > 0)
            {
                memset(&Base[i].head, 0, bytes);
            }
            *pNumber = i;
            NumOfElements = i;
            break;
        }
        if (Base[i].flag)
        {
            tailOrHead = Base[i].tail;
        }
        else
        {
            tailOrHead = Base[i].head;
        }
        if (Base[i].flag)
        {
            headOrTail = Base[i].head;
        }
        else
        {
            headOrTail = Base[i].tail;
        }
        if (i <= 0)
        {
            prevHeadOrTail = -1;
        }
        else
        {
            if (Base[i - 1].flag)
            {
                prevHeadOrTail = Base[i - 1].head;
            }
            else
            {
                prevHeadOrTail = Base[i - 1].tail;
            }
        }
        if (prevHeadOrTail >= 0 && prevHeadOrTail == tailOrHead)
        {
            if (Base[i].flag || !Base[i - 1].flag)
            {
                if (Base[i].flag && !Base[i - 1].flag)
                {
                    prevHeadOrTail--;
                }
            }
            else
            {
                prevHeadOrTail--;
            }
        }
        if (tailOrHead > headOrTail || (i > 0 && tailOrHead <= prevHeadOrTail))
        {
            if (Base[i].pIndex2)
            {
                delete[] ((int32_t *)Base[i].pIndex2);
                Base[i].pIndex2 = 0;
            }
            if (i < NumOfElements - 1)
            {
                memcpy(&Base[i], &Base[i + 1], sizeof(IndexBuffer1) * (NumOfElements - 1 - i));
            }
            memset(&Base[NumOfElements - 1], 0, sizeof(IndexBuffer1));
            NumOfElements = --*pNumber;
        }
    }
    pIdx = new IndexBuffer1[NumOfElements];
    memcpy((void *)pIdx, Base, sizeof(IndexBuffer1) * NumOfElements);
    qsort((void *)pIdx, NumOfElements, sizeof(IndexBuffer1), compareFistAndSecond);
    memset(Base, 0, sizeof(IndexBuffer1) * NumOfElements);
    i = 0;
    j = 0;
    while (i < NumOfElements)
    {
        if (pIdx[i].pIndex2)
        {
            head2 = pIdx[i].pIndex2->head2;
        }
        else
        {
            head2 = -1;
        }
        if (pIdx[i].pIndex2)
        {
            tail2 = pIdx[i].pIndex2->tail2;
        }
        else
        {
            tail2 = -1;
        }
        if (head2 >= 0 && tail2 >= 0)
        {
            memcpy(&Base[j], &pIdx[i], sizeof(IndexBuffer1));
            if (Base[j].flag)
            {
                sub_10002ED7(&Base[j]);
            }
            ++j;
        }
        else
        {
            pRes[pIdx[i].head].TypeCode[0] = 32;
        }
        ++i;
    }
    *pNumber = j;
    NumOfElementsa = j;
    for (k = 0; k < NumOfElementsa; ++k)
    {
        tail2 = Base[k].pIndex2->tail2;
        for (l = Base[k].pIndex2->head2; l <= tail2; ++l)
        {
            if (pRes[l].TypeCode[0] == C32 || !pRes[l].TypeCode[0])
            {
                pRes[l].TypeCode[0] = Base[0].flag != 0 ? C116 : C84;
            }
            if (pRes[l].TypeCode[1] == C32 || !pRes[l].TypeCode[1])
            {
                pRes[l].TypeCode[1] = C66;
            }
            if (pRes[l].TypeCode[2] == C32 || !pRes[l].TypeCode[2])
            {
                pRes[l].TypeCode[2] = C66;
            }
        }
    }
    for (m = Base[0].head; m <= tail; ++m)
    {
        if (pRes[m].TypeCode[1] == C32 || !pRes[m].TypeCode[1])
        {
            pRes[m].TypeCode[1] = C86;
        }
        if (pRes[m].TypeCode[2] == C32 || !pRes[m].TypeCode[2])
        {
            pRes[m].TypeCode[2] = C86;
        }
    }
    delete[] pIdx;
    return true;
};

// sub_1001AA20
CIndexWrapper *CIndexWrapper::setIndexBuf()
{
    this->indexBuf = (IndexBuffer1 *)this->head;
    return this;
};

// sub_1001AA40
int32_t *CIndexWrapper::cleanIndexBuf()
{
    int32_t *result;
    int32_t i;
    IndexBuffer1 *pBuf = (IndexBuffer1 *)this->head;

    for (i = 0; i < this->len; ++i)
    {
        if (pBuf[i].pIndex2)
        {
            delete[] pBuf[i].pIndex2;
        }
    }
    this->initHead();
    this->indexBuf20 = NULL;
    this->indexBuf2 = NULL;
    this->currentTail2 = 0;
    memset(this->head, 0, sizeof(IndexBuffer1) * this->len);
    result = this->getNumPointer();
    *result = 0;
    return result;
};

// sub_10002CB6
int32_t CIndexWrapper::getIndexHead()
{
    int32_t result;

    this->getNumPointer();
    if (*(int32_t *)this->getNumPointer() <= 0)
    {
        result = -1;
    }
    else
    {
        result = this->indexBuf->head;
    }
    return result;
};

// sub_10002CEA
int32_t CIndexWrapper::getHeadTail1(int32_t *head, int32_t *tail, int32_t *head2, int32_t *tail2)
{
    int32_t result;
    int32_t *pNumber;
    int32_t len;

    pNumber = this->getNumPointer();
    len = this->getLen();
    if (*pNumber <= 0)
    {
        *head = -1;
        *tail = -1;
        if (head2 && tail2)
        {
            *head2 = -1;
            *tail2 = -1;
        }
        memset((void *)this->head, 0, sizeof(IndexBuffer1) * len);
        this->indexBuf = (IndexBuffer1 *)this->head;
        this->indexBuf->head = -1;
        this->indexBuf->tail = -1;
        this->indexBuf->pIndex2 = NULL;
        this->indexBuf20 = NULL;
        this->indexBuf2 = NULL;
        this->currentTail2 = 0;
        *pNumber = 0;
        result = false;
    }
    else
    {
        this->currentTail2 = this->indexBuf->itemCount;
        this->indexBuf2 = this->indexBuf->pIndex2;
        this->indexBuf20 = this->indexBuf2;
        *head = this->indexBuf->head;
        *tail = this->indexBuf->tail;
        --*pNumber;
        this->indexBuf++;
        if (head2 && tail2)
        {
            result = this->getHeadTail2(head2, tail2);
        }
        else
        {
            result = true;
        }
    }
    return result;
};

// sub_10002E48
int32_t CIndexWrapper::getHeadTail2(int32_t *head, int32_t *tail)
{
    int32_t result;

    if (this->currentTail2 <= 0)
    {
        this->cleanIndexBuf2();
        *tail = -1;
        *head = -1;
        result = false;
    }
    else
    {
        if (this->indexBuf2)
        {
            *head = this->indexBuf2->head2;
            *tail = this->indexBuf2->tail2;
            --this->currentTail2;
            this->indexBuf2++;
        }
        else
        {
            *tail = -1;
            *head = -1;
        }
        result = true;
    }
    return result;
};

// sub_10002BA6
int32_t CIndexWrapper::createIndexBuf2()
{
    this->indexBuf20 = new IndexBuffer2[this->indexCount2];
    if (!this->indexBuf20)
    {
        return false;
    }
    memset((void *)this->indexBuf20, 0, sizeof(IndexBuffer2) * this->len);
    this->indexBuf2 = this->indexBuf20;
    this->indexBuf->pIndex2 = this->indexBuf2;
    this->indexBuf2->tail2 = -1;
    this->indexBuf2->head2 = -1;
    this->indexBuf2->flag2 = false;
    this->currentTail2 = 0;
    return true;
};

// sub_1001A640
int32_t CIndexWrapper::isCurrentTail2Zero()
{
    return this->currentTail2 == 0;
};
